<template>
	<u-popup :show="show" mode="bottom" @close="handleClose" @open="handleOpen" :duration="duration">
		<view class="commentPopup">
			<view class="commentPopup-input">
				<u--textarea class="textArea" v-model="commentValue" :placeholder="placeholder" autoHeight
					showConfirmBar :focus="true" :maxlength="maxlength" border="none" :adjust-position="false">
				</u--textarea>
				<view class="commentPopup-upLoad">
					<u-upload v-if="fileList.length > 0" :fileList="fileList" :maxCount="maxFileCount"
						:previewFullImage="true" name="1" ref="uUploadImage" multiple width="100rpx" height="100rpx"
						@afterRead="handleImageUpload" @delete="handleDeletePic">
						<image src="/static/add-image.png" mode="widthFix" style="width: 100rpx;height: 100rpx;">
						</image>
					</u-upload>
				</view>
			</view>
			<view class="commentPopup-footer">
				<view class="commentPopup-footer-operation">
					<view class="commentPopup-footer-operation-first" @click="handleOpenUpload">
						<image src="/static/picture.png" mode="aspectFill" :lazy-load="true"></image>
					</view>
				</view>
				<view class="commentPopup-footer-emitBtn">
					<u-button style="height: 60rpx;" type="error" text="提交" :disabled="!commentValue.trim()"
						shape="circle" @click="handleSubmit">
					</u-button>
				</view>
			</view>
		</view>
		<view class="" :style="{height: keyboardHeight + 'rpx' }"></view>

		<!-- 添加上传操作面板 -->
		<u-action-sheet :show="showUploadOptions" :actions="uploadActions" cancelText="取消" @select="handleUploadSelect"
			@close="showUploadOptions = false">
		</u-action-sheet>
	</u-popup>
</template>

<script>
	import config from '@/config/index.js'

	// 上传操作配置
	const UPLOAD_ACTIONS = [{
		name: '从相册选择照片',
		type: 'image',
		sourceType: ['album']
	}];

	// 常量定义
	const POST_IMAGE_PURPOSE = 'post_image';
	const POST_VIDEO_PURPOSE = 'post_video';
	const MAX_VIDEO_SIZE_MB = 100;
	const MAX_VIDEO_SIZE_BYTES = MAX_VIDEO_SIZE_MB * 1024 * 1024;

	export default {
		name: "CommentInput",
		props: {
			show: {
				type: Boolean,
				default: false
			},
			placeholder: {
				type: String,
				default: "爱评论的人运气都不差"
			},
			maxlength: {
				type: Number,
				default: 300
			},
			maxFileCount: {
				type: Number,
				default: 9
			},
			duration: {
				type: Number,
				default: 300
			},
			initialValue: {
				type: String,
				default: ''
			}
		},
		data() {
			return {
				commentValue: '',
				keyboardHeight: 0,
				fileList: [],
				showUploadOptions: false,
				uploadActions: UPLOAD_ACTIONS,
				currentUploadType: 'post',
				acceptType: 'image',
				videoList: [],
				isUploadingGlobally: false
			};
		},
		watch: {
			show(newVal) {
				if (newVal) {
					this.commentValue = this.initialValue;
				}
			},
			initialValue(newVal) {
				if (!this.show) {
					this.commentValue = newVal;
				}
			}
		},
		created() {
			uni.onKeyboardHeightChange((res) => {
				this.keyboardHeight = res.height * 2;
			});
		},
		methods: {
			showToast(message, icon = 'none') {
				uni.showToast({
					title: message,
					icon,
					duration: 3000
				});
			},

			handleClose() {
				this.$emit('close');
			},

			handleOpen() {
				this.$emit('open');
			},

			handleSubmit() {
				if (!this.commentValue.trim()) {
					this.showToast('请输入评论内容');
					return;
				}

				const filesToSubmit = this.prepareFilesForSubmit();
				const submitData = {
					content: this.commentValue.trim(),
					files: filesToSubmit
				};

				this.$emit('submit', submitData);
				this.commentValue = '';
				this.fileList = [];
			},

			handleOpenUpload() {
				this.showUploadOptions = true;
			},

			handleUploadSelect(action) {
				this.showUploadOptions = false;

				const config = {
					image: {
						method: 'chooseImage',
						params: {
							count: this.maxFileCount - this.fileList.length,
							sourceType: action.sourceType,
							sizeType: ['compressed'],
						}
					},
					video: {
						method: 'chooseVideo',
						params: {
							sourceType: action.sourceType
						}
					}
				} [action.type];

				if (!config) return;

				uni[config.method]({
					...config.params,
					success: (res) => {
						let files = [];
						if (action.type === 'image') {
							files = (res.tempFilePaths || []).map(path => ({
								url: path,
								path: path,
								tempFilePath: path
							}));
							if (res.tempFiles) {
								files = res.tempFiles.map((file, index) => ({
									url: file.path,
									path: file.path,
									tempFilePath: file.path,
									size: file.size,
									type: file.type,
									name: file.name || `image_${Date.now()}_${index}.jpg`
								}));
							}
						} else {
							files = [{
								url: res.tempFilePath,
								path: res.tempFilePath,
								tempFilePath: res.tempFilePath,
								width: res.width,
								height: res.height,
								size: res.size,
								duration: res.duration,
								type: 'video/mp4',
								name: `video_${Date.now()}.mp4`
							}];
						}

						const handler = action.type === 'image' ? 'handleImageUpload' : 'handleVideoUpload';
						if (files.length > 0) {
							this[handler]({
								file: files
							});
						}
					},
					fail: (error) => {
						console.error('选择文件失败:', error);
						this.showToast('选择文件失败');
					}
				});
			},

			async handleImageUpload(event) {
				await this.handleFileUpload({
					file: event.file,
					fileListKey: 'fileList',
					videoListKey: 'videoList',
					acceptTypeKey: 'acceptType'
				});
			},

			async handleVideoUpload(event) {
				await this.handleFileUpload({
					file: event.file,
					fileListKey: 'fileList',
					videoListKey: 'videoList',
					acceptTypeKey: 'acceptType'
				});
			},

			async handleFileUpload({
				file,
				fileListKey,
				videoListKey,
				acceptTypeKey
			}) {
				const lists = [].concat(file);
				if (lists.length === 0) return;

				if (this[fileListKey].length > 0 && this.isVideoFile(lists[0])) {
					this.showToast('只能上传图片或视频之一，已为您清空图片', 'none');
					this[fileListKey] = [];
				}

				if (this.isVideoFile(lists[0])) {
					this[acceptTypeKey] = 'video';
				} else {
					this[acceptTypeKey] = 'image';
				}

				if (this[acceptTypeKey] === 'video') {
					await this.handleVideoFileUpload(lists[0], videoListKey);
				} else {
					await this.handleImageFilesUpload(lists, fileListKey);
				}
			},

			isVideoFile(file) {
				if (file.type && file.type.includes('video')) {
					return true;
				}
				if (file.tempFilePath && file.tempFilePath.includes('.mp4')) {
					return true;
				}
				if (file.path && file.path.includes('.mp4')) {
					return true;
				}
				if (file.url && file.url.includes('.mp4')) {
					return true;
				}
				return false;
			},

			async handleImageFilesUpload(lists, fileListKey) {
				this.isUploadingGlobally = true;

				const newFilePlaceholders = lists.map(item => ({
					url: item.url || item.path || item.tempFilePath,
					status: "uploading",
					message: "上传中...",
					originalName: item.name || `image_${Date.now()}.jpg`,
					mimeType: item.type || 'image/jpeg',
					qiniuKey: null,
					_tempPath: item.url || item.path || item.tempFilePath
				}));

				this[fileListKey] = [...this[fileListKey], ...newFilePlaceholders];

				try {
					for (let i = 0; i < newFilePlaceholders.length; i++) {
						const placeholder = newFilePlaceholders[i];
						const currentIndex = this[fileListKey].findIndex(item => item._tempPath === placeholder
							._tempPath);
						if (currentIndex !== -1) {
							await this.uploadSingleFile(
								placeholder._tempPath,
								placeholder.originalName,
								POST_IMAGE_PURPOSE,
								fileListKey,
								currentIndex
							);
						}
					}
				} finally {
					this.isUploadingGlobally = false;
				}
			},

			async handleVideoFileUpload(fileItem, videoListKey) {
				const fileSize = fileItem.size || (fileItem.file ? fileItem.file.size : 0);

				if (fileSize > MAX_VIDEO_SIZE_BYTES) {
					this.showToast(`视频文件最大支持${MAX_VIDEO_SIZE_MB}MB`, 'none');
					this[videoListKey] = [{
						url: fileItem.url,
						status: 'fail',
						message: `超过${MAX_VIDEO_SIZE_MB}MB限制`
					}];
					return;
				}

				const originalName = fileItem.name || `video_${Date.now()}.mp4`;
				const mimeType = fileItem.type || 'video/mp4';

				const videoObject = {
					url: fileItem.url,
					width: fileItem.width,
					height: fileItem.height,
					status: 'uploading',
					message: '上传中...',
					originalName,
					mimeType,
					qiniuKey: null
				};

				this[videoListKey] = [videoObject];
				await this.uploadSingleFile(fileItem.url, originalName, POST_VIDEO_PURPOSE, videoListKey, 0);
			},

			async uploadSingleFile(fileUrl, originalName, purpose, listKey, index) {
				try {
					uni.showLoading({
						mask: true,
						title: '上传中'
					});

					const qiniuCdnUrl = await this.uploadFileToQiniu(fileUrl, purpose);

					const updatedFile = {
						...this[listKey][index],
						url: qiniuCdnUrl,
						status: 'success',
						message: '上传成功'
					};

					this.$set(this[listKey], index, updatedFile);
					uni.hideLoading();
				} catch (error) {
					uni.hideLoading();
					this[listKey].splice(index, 1);
					this.showToast(error.message || `文件上传失败`);
				}
			},

			async uploadFileToQiniu(fileUrl, purpose) {
				return new Promise((resolve, reject) => {
					const base_url = config.baseURL;
					uni.uploadFile({
						url: base_url + '/qnyUpload/upload',
						filePath: fileUrl,
						name: "file",
						header: {
							'Authorization': uni.getStorageSync('token') || '',
							'Accept': 'application/json'
						},
						success: (res) => {
							if (res.statusCode === 413) {
								reject(new Error('文件大小超过服务器限制，请选择较小的文件'));
								return;
							}
							try {
								const responseData = typeof res.data === 'string' ? JSON.parse(res
									.data) : res.data;
								if (responseData.code === 200) {
									resolve(responseData.url);
								} else {
									reject(new Error(responseData.msg || '上传失败'));
								}
							} catch (error) {
								reject(new Error('服务器响应格式错误'));
							}
						},
						fail: (err) => {
							if (err.errMsg && err.errMsg.includes('request:fail')) {
								reject(new Error('网络连接失败，请检查网络设置'));
							} else {
								reject(new Error('网络请求失败'));
							}
						}
					});
				});
			},

			handleDeletePic(event) {
				this.fileList.splice(event.index, 1);
			},

			prepareFilesForSubmit() {
				const currentUserId = this.$store?.state?.userInfo?.userId || 0;
				const isImageUpload = this.acceptType === 'image';

				return this.processFileList(
					isImageUpload ? this.fileList : this.videoList,
					currentUserId,
					isImageUpload
				);
			},

			processFileList(fileList, userId, isImage) {
				return fileList
					.filter(item => item.status === 'success' && item.url)
					.map(item => ({
						userId,
						fileName: item.originalName,
						fileUrl: item.url,
						fileType: item.mimeType,
						...(isImage ? {
							previewImgUrl: item.url,
							isImage: 1
						} : {
							width: item.width,
							height: item.height,
							isImage: 0
						})
					}));
			},

			clear() {
				this.commentValue = '';
				this.fileList = [];
			}
		}
	};
</script>

<style lang="scss" scoped>
	.commentPopup {
		padding: 20rpx 40rpx;
		margin-bottom: 20rpx;

		.commentPopup-input {
			background-color: #f5f5f5;
			border-radius: 20rpx;

			.textArea {
				background-color: #f5f5f5;
				border-radius: 20rpx;
			}

			.commentPopup-upLoad {
				margin-left: 20rpx;

				::v-deep .u-upload__wrap {
					display: flex;
					flex-wrap: nowrap;
					overflow-x: auto;

					::v-deep .u-upload__item {
						flex-shrink: 0;
						margin-right: 10rpx;
					}
				}
			}
		}

		.commentPopup-footer {
			display: flex;
			justify-content: flex-end;
			margin-top: 20rpx;

			.commentPopup-footer-operation {
				flex: 1;
				display: flex;

				.commentPopup-footer-operation-first {
					width: 50rpx;
					height: 50rpx;

					image {
						width: 50rpx;
						height: 50rpx;
					}
				}
			}

			.commentPopup-footer-emitBtn {
				width: 120rpx;
			}
		}
	}
</style>